package templateExecel2.fram;

import com.google.common.base.Joiner;
import org.checkerframework.checker.units.qual.A;
import templateExecel2.utils.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class TemplateCellParser2 {

    private static Pattern ARRAY_PATTERN = Pattern.compile("\\[([^\\[\\]]+)]");

    static class Result {

        private LinkedHashMap<String, LinkedHashSet<String>> checkJsMap;

        LinkedHashMap<String, LinkedHashSet<String>> getCheckJsMap() {
            return checkJsMap;
        }

        private String expression;

        String getExpression() {
            return expression;
        }

        private List<String> commands;

        public List<String> getCommands() {
            return commands;
        }
    }

    //表达式${xxx}
    private static Pattern EXPRESSION_PATTERN = Pattern.compile("\\$\\{([^{}]*)}");

    private static String handleExpression(String s) {

        Matcher matcher = EXPRESSION_PATTERN.matcher(s);

        int end = 0;

        List<String> all = new LinkedList<>();
        while (matcher.find()) {
            if (matcher.start() > end) {


                String st = "'" + s.substring(end, matcher.start()).replace("'", "\\\'") + "'";
                all.add(st);
            }
            String group = matcher.group(1);
            all.add(group);
            end = matcher.end();
        }

        if (all.size() > 0) {
            if (end < s.length() - 1) {
                all.add("'" + s.substring(end).replace("'", "\\\\'") + "'");
            }
            String join = Joiner.on(",").join(all);
            return "concat(" + join + ")";
        } else {
            return "'" + s + "'";
        }
    }

    private static Pattern command_patten = Pattern.compile("\\$[a-z]+\\([a-z0-9]*\\)");

    private static void handleCommand(String s, Result result) {
        Matcher matcher = command_patten.matcher(s);

        if (matcher.find()) {
            result.commands = new ArrayList<>();
            result.commands.add(matcher.group());
        }

        while (matcher.find()) {
            if (!result.commands.contains(matcher.group())) {
                result.commands.add(matcher.group());
            }
        }
    }


    /*
        变换数组
     */

    //提取数组引用
    static Result parse(String s) {//提取并变换数组表达式

        s = handleExpression(s);//对换行符进行一次转换

        //替换掉换行符
        s = s.replace("\n", "\\n");

        //对s中的换行符再进行一次转译

        Result result = new Result();

        //提取指令
        handleCommand(s, result);

        result.checkJsMap = new LinkedHashMap<>();

        //首先提取字符串
        StringUtils.StringRecover extract = StringUtils.extract(s);
        s = extract.getResult();

        //提取数组表达式
        Matcher matcher = ARRAY_PATTERN.matcher(s);


        //从一个简单的操作

        while (matcher.find()) {

            String exp = "";

            int end = matcher.start() - 1;
            while (true) {
                //反向查找成对的中括号
                StringUtils.SubStringResult reverse = StringUtils.pairingSubStringReverse(s, end, ']', '[');

                if (reverse != null && reverse.endEqualsFrom()) {

                    //向前做一次推移
                    end = reverse.getStart() - 1;

                    //构建表达式
                    exp = reverse.getSubString() + exp;

                } else {//跳出循环
                    break;
                }
            }


            //处理中括号
            StringUtils.SubStringResult reverse = StringUtils.pairingSubStringReverse(s, end, ')', '(');
            if (reverse != null && reverse.endEqualsFrom()) {
                end = reverse.getStart() - 1;
                exp = reverse.getSubString() + exp;
            }

            //查找查找变量声明
            reverse = StringUtils.rejectCharSubStringReverse(s, end, ',', '(');

            if (reverse != null && reverse.endEqualsFrom()) {
                end = reverse.getStart() - 1;
                exp = reverse.getSubString() + exp;
                String h = exp;
                String group1 = matcher.group(1);
                LinkedHashSet<String> linkedHashSet = result.checkJsMap.computeIfAbsent(group1, k -> new LinkedHashSet<>());
                String js = h + "&&" + h + ".length" + "&&" + h + ".length>" + group1 + "?false:true;";//返回是否已经超出预期值

                linkedHashSet.add(extract.recover(js));

            }
        }


        result.expression = extract.recover(s);
        return result;

    }


    public static void main(String[] args) {

        String s = "${concat(fill(list[j])[i][k])}";

        Matcher matcher = ARRAY_PATTERN.matcher(s);


    }

}
